package Day08.RPCDemo02.src.cn.tedu.utils;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NIOUtils {
    private NIOUtils() {}
    private static Selector selector = null;
    private static SocketChannel sc = null;

    static {
        try {
            selector = Selector.open();
            sc = SocketChannel.open();
            sc.configureBlocking(false);
            sc.connect(new InetSocketAddress("localhost", 9999));
            while(!sc.finishConnect()){}
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * NIO通信
     * 协议：长度#字节...
     */
    public static byte[] call(byte[] data) {
        try {
            sc.register(selector, SelectionKey.OP_WRITE);
            while(true){
                selector.select();
                Set<SelectionKey> set = selector.selectedKeys();
                Iterator<SelectionKey> it = set.iterator();
                while(it.hasNext()){
                    SelectionKey key = it.next();

                    if(key.isWritable()){
                        SocketChannel sc = (SocketChannel) key.channel();
                        byte[] sendData = ArrayUtils.append((data.length + "#").getBytes(), data);
                        ByteBuffer buffer = ByteBuffer.wrap(sendData);
                        while(buffer.hasRemaining()){
                            sc.write(buffer);
                        }
                        sc.register(selector, SelectionKey.OP_READ);
                    }else if(key.isReadable()){
                        SocketChannel sc = (SocketChannel) key.channel();
                        ByteBuffer temp = ByteBuffer.allocate(1);
                        String lenStr = "";
                        while(!lenStr.endsWith("#")){
                            sc.read(temp);
                            lenStr += new String(temp.array());
                            temp.clear();
                        }
                        int len = Integer.parseInt(lenStr.substring(0,lenStr.length()-2));
                        ByteBuffer buffer = ByteBuffer.allocate(len);
                        while(buffer.hasRemaining()){
                            sc.read(buffer);
                        }
                        byte[] retData = buffer.array();
                        return retData;
                    }
                    it.remove();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

    }

}
